package com.qen.boot;

import com.qen.encrypt.inter.Decrypt;
import com.qen.encrypt.inter.Encrypt;
import com.qen.encrypt.inter.EncryptGroup;
import com.qen.encrypt.inter.NoSign;
import com.qen.encrypt.inter.ValidSign;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * 参数加密和签名防篡改ControllerDemo
 * @author licz
 * @data 2025年07月15日 14:25
 */
@RestController
@RequestMapping("/encrypt")
@ValidSign
public class DemoController {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @PostMapping("/test")
    // 意为返回值加密，返回值中message和data参与加密，前端通过 encrypt = 1 判断参数是否需要解密
    @Encrypt({"data"})
    // 意为当前Method使用group:qenqen组的key为加密Key
    @EncryptGroup("qenqen")
    // @Decrypt 注解意为为当前的参数进行加密，注解实体时，实体中的每个参数都进行解密
    @ValidSign
    public ResponseEntity test(@RequestBody @Decrypt EncryptEntityVo vo, @NoSign @RequestParam("value") @Decrypt String value) {
        logger.info(vo.toString());
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", value, "name", vo.getName(), "age", vo.getAge())));
    }

    @PostMapping("/formdata")
    public ResponseEntity formdata(@Decrypt EncryptEntityVo vo, @RequestParam("sex") Integer sex, @RequestParam("value") @Decrypt String value) {
        logger.info(vo.toString());
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", value, "name", vo.getName(), "age", vo.getAge(),
                "sex", sex)));
    }

    @PostMapping("/urlencode")
    public ResponseEntity urlencode(@Decrypt EncryptEntityVo vo, @RequestParam("sex") Integer sex, @RequestParam("value") @Decrypt String value) {
        logger.info(vo.toString());
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", value, "name", vo.getName(), "age", vo.getAge(),
                "sex", sex)));
    }

    @PutMapping("/put/test")
    @Encrypt({"data", "message"})
    @EncryptGroup("qenqen")
    public ResponseEntity testPut(@RequestBody @Decrypt EncryptEntityVo vo) {
        logger.info(vo.toString());
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", "value", "name", vo.getName(), "age", vo.getAge())));
    }

    @PutMapping("/put/formdata")
    public ResponseEntity formdataPut(@Decrypt EncryptEntityVo vo, @RequestParam("sex") Integer sex) {
        logger.info(vo.toString());
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", "value", "name", vo.getName(), "age", vo.getAge(),
                "sex", sex)));
    }

    @PutMapping("/put/urlencode")
    public ResponseEntity urlencodePut(@Decrypt EncryptEntityVo vo, @RequestParam("sex") Integer sex) {
        logger.info(vo.toString());
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", "value", "name", vo.getName(), "age", vo.getAge(),
                "sex", sex)));
    }

    @DeleteMapping("/delete/test")
    @Encrypt
    @EncryptGroup("qenqen")
    public ResponseEntity testDelete(@RequestBody @Decrypt EncryptEntityVo vo) {
        logger.info(vo.toString());
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", "value", "name", vo.getName(), "age", vo.getAge())));
    }

    @DeleteMapping("/delete/formdata")
    public ResponseEntity formdataDelete(@Decrypt EncryptEntityVo vo, @RequestParam("sex") Integer sex) {
        logger.info(vo.toString());
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", "value", "name", vo.getName(), "age", vo.getAge(),
                "sex", sex)));
    }

    @DeleteMapping("/delete/urlencode")
    public ResponseEntity urlencodeDelete(@Decrypt EncryptEntityVo vo, @RequestParam("sex") Integer sex) {
        logger.info(vo.toString());
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", "value", "name", vo.getName(), "age", vo.getAge(),
                "sex", sex)));
    }

    @GetMapping("/getParam")
    public ResponseEntity getParam(@Decrypt @RequestParam("name") String name, @RequestParam("value") String value) {
        logger.info(name);
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", value, "name", name)));
    }

    @GetMapping("/getPath/{name}")
    public ResponseEntity getPath(@PathVariable("name") String name, @Decrypt @RequestParam("desc") String desc) {
        logger.info(name);
        return ResponseEntity.ok(ApiResponse.success(Map.of("key", "value",
                "name", name, "desc", desc
        )));
    }

    @Data
    public static class EncryptEntityVo {
        private String name;
        private Integer age;
        private Long uid;
    }

    @Data
    public static class ApiResponse {

        private int code;
        private boolean result;
        private String message;
        private Object data;
        private int encrypt = 0;

        public ApiResponse(int code, String message, Object data, boolean result) {
            this.code = code;
            this.message = message;
            this.data = data;
            this.result = result;
            this.encrypt = 0;
        }

        public static ApiResponse success(Object data) {
            return new ApiResponse(200, "请求成功", data, true);
        }


    }


}

